// 缓存工具模块
// 用于管理API请求的缓存，避免重复请求

/**
 * 请求缓存接口
 */
interface RequestCache {
  [key: string]: Promise<any> | null
}

/**
 * 全局请求缓存对象 - 确保在整个应用中只有一个缓存实例
 */
const requestCache: RequestCache = {}

/**
 * 设置请求缓存
 * @param key 缓存键名
 * @param promise 请求的Promise对象
 */
export const setRequestCache = (key: string, promise: Promise<any> | null): void => {
  requestCache[key] = promise
}

/**
 * 获取请求缓存
 * @param key 缓存键名
 * @returns 缓存的Promise对象，如果不存在则返回null
 */
export const getRequestCache = (key: string): Promise<any> | null => {
  const cache = requestCache[key]

  return cache
}

/**
 * 清除请求缓存
 * @param key 缓存键名，如果不传则清除所有缓存
 */
export const clearRequestCache = (key?: string): void => {
  if (key) {
    delete requestCache[key] // 使用delete而不是设置为null，避免引用问题
  } else {
    // 清空缓存对象
    Object.keys(requestCache).forEach(cacheKey => {
      delete requestCache[cacheKey]
    })
  }
}

/**
 * 检查并获取缓存或创建新请求
 * 这个高阶函数是防止重复请求的核心，它确保在任何情况下都只会有一个相同的请求在运行
 * @param key 缓存的键名
 * @param requestFn 要执行的请求函数
 * @returns Promise<any> 请求结果
 */
export const cachedRequest = async <T>(key: string, requestFn: () => Promise<T>): Promise<T> => {
  // 检查是否已有正在进行的请求
  const existingRequest = getRequestCache(key)
  if (existingRequest) {
    return existingRequest as Promise<T>
  }

  try {
    // 执行实际的请求

    const newRequest = requestFn()

    // 保存请求到缓存中
    setRequestCache(key, newRequest)

    // 请求完成后，从缓存中移除（可选，取决于是否需要缓存结果）
    // 在这里我们不移除，因为我们希望重用正在进行的请求

    return newRequest
  } catch (error) {
    // 请求失败时清除缓存

    clearRequestCache(key)
    throw error
  }
}

/**
 * 获取当前缓存状态（用于调试）
 */
export const getCacheStatus = (): RequestCache => {
  return { ...requestCache }
}
